package cn.com.libertymutual.core.redis.util;

import java.util.Set;
import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import cn.com.libertymutual.core.redis.config.RedisProperties;

@Component("redisUtils")
public class RedisUtils {
	private Logger log = LoggerFactory.getLogger(getClass());

	@Autowired
	@Qualifier("stringRedis")
	private StringRedisTemplate stringRedis;

	@Autowired
	@Qualifier("redisTemplate")
	private RedisTemplate<String, Object> redisTemplate;

	@Resource
	private RedisProperties redisProperties;

	/**
	 * 注意上测试的时候修改该值为cxb-plat
	 */
	// TODO 注意上测试的时候修改该值为
	// 开发直接无后缀
	private static final String DEF_PREFIX = "cxb-plat"; // 默认前缀
	private static final String KEY_SPLIT = ":"; // 用于隔开缓存前缀与缓存键值

	// private static final String DEF_PREFIX = ""; //默认前缀
	// private static final String KEY_SPLIT = ""; //用于隔开缓存前缀与缓存键值

	/**
	* 设置缓存 
	* @param prefix 缓存前缀（用于区分缓存，防止缓存键值重复）
	* @param key    缓存key
	* @param value  缓存value
	*/
	public void setString(String prefix, String key, String value) {
		stringRedis.opsForValue().set(prefix + KEY_SPLIT + key, value);
		log.debug(String.format("RedisUtil:set cache key=%s,value=%s", prefix + KEY_SPLIT + key, value));
	}

	public void setString(String key, String value) {
		setString(DEF_PREFIX, key, value);
	}

	/**
	 * 设置缓存，并且自己指定过期时间
	 * @param prefix
	 * @param key
	 * @param value
	 * @param expireTime 过期时间
	 */
	public void setStringWithExpireTime(String prefix, String key, String value, int expireTime) {
		stringRedis.opsForValue().set(prefix + KEY_SPLIT + key, value, expireTime, TimeUnit.SECONDS);
		// LOGGER.debug("RedisUtil:setWithExpireTime cache
		// key={},value={},expireTime={}", prefix + KEY_SPLIT + key, value,
		// expireTime);
	}

	public void setStringWithExpireTime(String key, String value, int expireTime) {
		setStringWithExpireTime(DEF_PREFIX, key, value, expireTime);
	}

	/**
	 * 设置缓存，并且由配置文件指定过期时间
	 * @param prefix
	 * @param key
	 * @param value
	 */
	public void setStringWithExpireTime(String prefix, String key, String value) {
		int EXPIRE_SECONDS = redisProperties.getExpireSeconds();
		stringRedis.opsForValue().set(prefix + KEY_SPLIT + key, value, EXPIRE_SECONDS, TimeUnit.SECONDS);
		// LOGGER.debug("RedisUtil:setWithExpireTime cache
		// key={},value={},expireTime={}", prefix + KEY_SPLIT + key, value,
		// EXPIRE_SECONDS);
	}

	public void setStringWithExpireTime(String key, String value) {
		setStringWithExpireTime(DEF_PREFIX, key, value);
	}

	/**
	 * 获取指定key的缓存
	 * @param prefix
	 * @param key
	 */
	public String getString(String prefix, String key) {
		String value = stringRedis.opsForValue().get(prefix + KEY_SPLIT + key);
		// LOGGER.debug("RedisUtil:get cache key={},value={}", prefix + KEY_SPLIT + key,
		// value);
		return value;
	}

	public String getString(String key) {
		return getString(DEF_PREFIX, key);
	}

	/**
	* 设置缓存 
	* @param prefix 缓存前缀（用于区分缓存，防止缓存键值重复）
	* @param key    缓存key
	* @param value  缓存value
	*/
	public void set(String prefix, String key, Object value) {
		redisTemplate.opsForValue().set(prefix + KEY_SPLIT + key, value);
		log.debug(String.format("RedisUtil:set cache key=%s,value=%s", prefix + KEY_SPLIT + key, value));
	}

	public void set(String key, Object value) {
		set(DEF_PREFIX, key, value);
	}

	/**
	 * 设置缓存，并且自己指定过期时间
	 * @param prefix
	 * @param key
	 * @param value
	 * @param expireTime 过期时间
	 */
	public void setWithExpireTime(String prefix, String key, Object value, int expireTime) {
		redisTemplate.opsForValue().set(prefix + KEY_SPLIT + key, value, expireTime, TimeUnit.SECONDS);
		// LOGGER.debug("RedisUtil:setWithExpireTime cache
		// key={},value={},expireTime={}", prefix + KEY_SPLIT + key, value,
		// expireTime);
	}

	public void setWithExpireTime(String key, Object value, int expireTime) {
		setWithExpireTime(DEF_PREFIX, key, value, expireTime);
	}

	/**
	 * 设置缓存，并且由配置文件指定过期时间
	 * @param prefix
	 * @param key
	 * @param value
	 */
	public void setWithExpireTime(String prefix, String key, Object value) {
		int EXPIRE_SECONDS = redisProperties.getExpireSeconds();
		redisTemplate.opsForValue().set(prefix + KEY_SPLIT + key, value, EXPIRE_SECONDS, TimeUnit.SECONDS);
		// LOGGER.debug("RedisUtil:setWithExpireTime cache
		// key={},value={},expireTime={}", prefix + KEY_SPLIT + key, value,
		// EXPIRE_SECONDS);
	}

	public void setWithExpireTime(String key, Object value) {
		setWithExpireTime(DEF_PREFIX, key, value);
	}

	/**
	 * 获取指定key的缓存
	 * @param prefix
	 * @param key
	 */
	public Object get(String prefix, String key) {
		return redisTemplate.opsForValue().get(prefix + KEY_SPLIT + key);
	}

	public Object get(String key) {
		return get(DEF_PREFIX, key);
	}

	@SuppressWarnings("unchecked")
	public <T> T get(String key, Class<T> clazz) {

		return (T) get(DEF_PREFIX, key);
	}
	/*
	 * public <T> T get( String prefix, String key, Class<T> clazz ) {
	 * 
	 * //return (T)redisTemplate.opsForValue().get(prefix + KEY_SPLIT + key); return
	 * get(prefix, key, clazz); }
	 */

	/**
	 * 删除指定key的缓存
	 * @param prefix
	 * @param key
	 */
	public void deleteWithPrefix(String prefix, String key) {
		stringRedis.delete(prefix + KEY_SPLIT + key);
		// LOGGER.debug("RedisUtil:delete cache key={}", prefix + KEY_SPLIT + key);
	}

	public void deleteWithPrefix(String key) {
		deleteWithPrefix(DEF_PREFIX, key);
	}

	public void delete(String key) {
		stringRedis.delete(key);
		// LOGGER.debug("RedisUtil:delete cache key={}", key);
	}

	public long incr(String key) {
		return redisTemplate.opsForValue().increment(DEF_PREFIX + KEY_SPLIT + key, 1);
		// return redisTemplate.getConnectionFactory().getClusterConnection().incr(
		// (DEF_PREFIX+key).getBytes() );
	}

	public long incrBy(String key, long value) {
		return redisTemplate.getConnectionFactory().getClusterConnection().incrBy((DEF_PREFIX + KEY_SPLIT + key).getBytes(), value);
	}

	public boolean hashKey(String key) {
		return redisTemplate.hasKey(DEF_PREFIX + KEY_SPLIT + key);
	}

	public void deletelike(String key) {
		Set<String> keys = redisTemplate.keys(DEF_PREFIX + KEY_SPLIT + key + "*");
		stringRedis.delete(keys);
		// LOGGER.debug("RedisUtil:delete cache key={}", key);
	}

}
